﻿using EFCore.Context;
using EFCore.Model;
using EFCore.Services;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;

namespace EFCore.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SeckillsController : ControllerBase
    {
        private readonly ISeckillService SeckillService;
        private readonly IMemoryCache memoryCache;// 本地缓存


        public SeckillsController(ISeckillService seckillService)
        {
            SeckillService = seckillService;
        }

        // GET: api/Seckills 获取所有秒杀商品
        [HttpGet]
        // [HttpCacheExpiration(NoStore=false, MaxAge=10000)]
        public ActionResult<IEnumerable<Seckill>> GetSeckills()
        {
            // 1、业务信息
            Console.WriteLine("查询秒杀商品信息");
            // 2、查询数据库
            List<Seckill> seckills = SeckillService.GetSeckills().ToList();

            #region 1、本地缓存
            {
                /*// 1、先查询缓存
                List<Seckill> seckills = memoryCache.Get<List<Seckill>>("seckills");
                if (seckills == null)
                {
                    // 1.1 查询数据库
                    seckills = SeckillService.GetSeckills().ToList();

                    memoryCache.Set<List<Seckill>>("seckills", seckills);
                }
                return seckills;*/
            }
            #endregion

            #region 2、本地缓存-安全
            {
                /* Console.WriteLine("获取秒杀数据");
                 List<Seckill> seckills = null;
                 bool flag = memoryCache.TryGetValue<List<Seckill>>("seckills", out seckills);
                 if (!flag)
                 {
                     // 1.1 查询数据库
                     seckills = SeckillService.GetSeckills().ToList();
                     // 1.2 添加到缓存
                     MemoryCacheEntryOptions memoryCacheEntryOptions = new MemoryCacheEntryOptions();
                     // 1、过期时间(保证数据和源头一致)
                     memoryCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromSeconds(3);
                     // 2、设置缓存量大小。(保证系统不影响其他操作)
                     memoryCacheEntryOptions.SetSize(1024);
                     // 3、方案：使用异步更新。
                     memoryCacheEntryOptions.RegisterPostEvictionCallback((key, value, reason, state) => {
                         // 1、key = seckills
                         // 2、value = List<Seckill>
                         // 3、reason = 回收的原因
                         // 4、state = 是否成功，是否失败
                         Console.WriteLine($"缓存自动失效：key:{key},value:{value},reason:{reason},state:{state}");

                         // 1、查询数据库的代码。
                         // 自动同步：
                         // 1、根据key查询数据库，查询秒杀商品数据
                         // 2、然后把查询秒杀商品数据存储到数据库中。
                         // 扩展：数据异构形式。
                     });
                     // 4、如果数据量缓存数据量，比较大。1000条数据
                     //    都会设置过期时间。

                     // 5、优先级设置。
                     memoryCacheEntryOptions.Priority = CacheItemPriority.High;

                     memoryCache.Set<List<Seckill>>("seckills", seckills, memoryCacheEntryOptions);
                 }
                 return seckills;*/
            }
            #endregion

            #region 3、分布式缓存
            {
                /* Console.WriteLine("获取秒杀数据");
                 // 1、先查询redis分布式缓存
                 string seckillsString = distributedCache.GetString("seckills");
                 List<Seckill> seckills = null;
                 if (string.IsNullOrEmpty(seckillsString))
                 {
                     // 1.1 查询数据库
                     seckills = SeckillService.GetSeckills().ToList();
                     seckillsString = JsonConvert.SerializeObject(seckills);

                     // 设置过期的时间。
                     var distributedCacheEntryOptions = new DistributedCacheEntryOptions();
                     distributedCacheEntryOptions.AbsoluteExpirationRelativeToNow = TimeSpan.FromDays(3);
                     // 1.2 存储到redis中
                     distributedCache.SetString("seckills", seckillsString, distributedCacheEntryOptions);
                 }

                 // 1.3反序列化成对象
                 seckills = JsonConvert.DeserializeObject<List<Seckill>>(seckillsString);
                 return seckills;*/
            }
            #endregion

            //HttpCLient
            //  HttpContext.Response.Headers.Add("cache-control", "max-age=60,public");
            // HttpContext.Response.Headers.Add("etag","5c20abbd-e2e8");
            // HttpContext.Response.Headers.Add("last-modified", "Mon, 24 Dec 2022 09:49:49 GMT");

            // HttpContext.Response.Headers.Add("vary", "Accept-Encoding");

            // 会执行很长时间
            // p.ProcessTransaction(new Customer(Guid.NewGuid().ToString()));
            return seckills;
        }
    }
}
